package com.clx.loadbalancer.impl;

import com.clx.CrpcBootstrap;
import com.clx.exceptions.LoadBalancerException;
import com.clx.loadbalancer.AbstractLoadBalancer;
import com.clx.loadbalancer.Selector;

import java.net.InetSocketAddress;
import java.nio.channels.Channel;
import java.util.List;

public class MinmumResponseTimeLoadBalancer extends AbstractLoadBalancer {
    @Override
    protected Selector getSelector(List<InetSocketAddress> serviceList) {
        return new MinimumResponseTimeSelector(serviceList);
    }

    private static class MinimumResponseTimeSelector implements Selector {

        private final List<InetSocketAddress> serviceList; // 保存原始服务列表，用于缓存为空时回退

        public MinimumResponseTimeSelector(List<InetSocketAddress> serviceList) {
            this.serviceList = serviceList;
        }


        @Override
        public InetSocketAddress getNext() {
            // 第一步：检查响应时间缓存是否有数据
            if (CrpcBootstrap.ANSWER_TIME_CHANNEL_CACHE.isEmpty()
                    || CrpcBootstrap.ANSWER_TIME_CHANNEL_CACHE.firstEntry() == null) {
                // 缓存为空，从原始服务列表回退选择（这里选第一个，也可改为随机等策略）
                if (serviceList == null || serviceList.isEmpty()) {
                    throw new LoadBalancerException("No available service addresses.");
                }
                return serviceList.get(0);
            }
            // 直接从缓存中获取一个可用的就行了
            Channel channel = (Channel) CrpcBootstrap.CHANNEL_CACHE.values().toArray()[0];

            // 第二步：缓存有数据，取“响应时间最短”的 Channel 对应的地址
            return (InetSocketAddress) CrpcBootstrap.ANSWER_TIME_CHANNEL_CACHE
                    .firstEntry().getValue().remoteAddress();
        }

    }
}